package org.jeecg.modules.rooms.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.CommonUtils;
import org.jeecg.common.util.TokenUtils;
import org.jeecg.modules.business.entity.BusHotel;
import org.jeecg.modules.business.entity.BusHousePriceSchemeLayout;
import org.jeecg.modules.business.service.IBusHousePriceSchemeLayoutService;
import org.jeecg.modules.business.service.impl.BusHotelServiceImpl;
import org.jeecg.modules.rooms.DTO.CesRoomLayoutDto;
import org.jeecg.modules.rooms.DTO.CesRoomLayoutRemoveDto;
import org.jeecg.modules.rooms.DTO.CesRoomLayoutSearchDto;
import org.jeecg.modules.rooms.Vo.CesRoomLayoutVo;
import org.jeecg.modules.rooms.entity.CesHousePriceScheme;
import org.jeecg.modules.rooms.entity.CesRoomLayout;
import org.jeecg.modules.rooms.mapper.CesRoomLayoutMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.sql.Time;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 租户房型记录表 服务实现类
 * </p>
 *
 * @author fendo
 * @since 2023-03-01
 */
@Service
public class CesRoomLayoutServiceImpl extends ServiceImpl<CesRoomLayoutMapper, CesRoomLayout> implements IService<CesRoomLayout> {

    @Resource
    private CesRoomLayoutMapper cesRoomLayoutMapper;

    @Resource
    private BusHotelServiceImpl busHotelService;

    @Resource
    CesHousePriceSchemeServiceImpl housePriceSchemeService;
    @Resource
    IBusHousePriceSchemeLayoutService housePriceSchemeLayoutService;


    /**
     * @Desc: 分页查询房型数据
     * @param searchDto
     * @return
     */
    public Result findRoomLayoutList(CesRoomLayoutSearchDto searchDto){
        QueryWrapper<CesRoomLayout> queryWrapper = new QueryWrapper<>();
        if(!StringUtils.isBlank(searchDto.getHotelName())){
            //查询当前这个人 管理的酒店名称like 参数 的酒店IDS
            List<BusHotel> busHotelList = busHotelService.findHotelsByHotelName(searchDto.getHotelName());
            List<String> busHotelIds = busHotelList.stream().map(v -> v.getId()).collect(Collectors.toList());
            if(!CollectionUtil.isEmpty(busHotelIds)){
                queryWrapper.in(CesRoomLayout.HOTEL_ID, busHotelIds);
            }
        }
        if(!StringUtils.isBlank(searchDto.getHotelId())) {
            queryWrapper.eq(CesRoomLayout.HOTEL_ID, searchDto.getHotelId());
        }
        //房型名称模糊查询
        if(!StringUtils.isBlank(searchDto.getName())){
            //处理百分号 mybatis plus bug 查询 % 出现全量数据
            queryWrapper.like(CesRoomLayout.NAME, CommonUtils.escapeChar(searchDto.getName()));
        }
        //查询上架状态
        if(searchDto.getAppState() != null && searchDto.getAppState().intValue() != 0){
            queryWrapper.eq(CesRoomLayout.APP_STATE, searchDto.getAppState().intValue());
        }
        //默认排序  未删除过滤 当前租户
        queryWrapper.eq(CesRoomLayout.TENANT_ID, TokenUtils.currentTenantId());
        queryWrapper.orderByDesc(CesRoomLayout.CREATEAT);
        queryWrapper.eq(CesRoomLayout.INVALID, false);

        IPage<CesRoomLayout> dataPage = cesRoomLayoutMapper.selectPage(new Page<>(searchDto.getPageNo().intValue(),searchDto.getPageSize().intValue()),queryWrapper);
        List<CesRoomLayoutVo> voList = new ArrayList<>();

        List<CesRoomLayout> data = dataPage.getRecords();
        List<String> hotelIds = data.stream().map(v -> v.getHotelId()).collect(Collectors.toList());
        List<BusHotel> hotels = busHotelService.findHotelsByIds(hotelIds);
        data.forEach( v -> {
            CesRoomLayoutVo vo = new CesRoomLayoutVo();
            BeanUtil.copyProperties(v,vo);
            Optional<BusHotel> busHotelOptional = hotels.stream().filter(c -> c.getId().equals(v.getHotelId())).findFirst();
            if(busHotelOptional.isPresent()){
                vo.setHotelName(busHotelOptional.get().getName());
            }
            voList.add(vo);
        });
        Map<String,Object> map = new HashMap<>();
        map.put("records",voList);
        map.put("total",dataPage.getTotal());
        return Result.OK(map);
    }


    /**
     * 创建房型
     * @param cesRoomLayoutDto
     * @return
     */
    public Result createRoomLayout(CesRoomLayoutDto cesRoomLayoutDto){
        //查询是否有相同名称的房型
        QueryWrapper<CesRoomLayout> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(CesRoomLayout.HOTEL_ID, cesRoomLayoutDto.getHotelId());
        queryWrapper.eq(CesRoomLayout.NAME,cesRoomLayoutDto.getName());
        queryWrapper.eq(CesRoomLayout.TENANT_ID, TokenUtils.currentTenantId());
        queryWrapper.eq(CesRoomLayout.INVALID, false);

        CesRoomLayout roomLayout =  cesRoomLayoutMapper.selectOne(queryWrapper);

        if(!ObjectUtils.isEmpty(roomLayout)) return Result.error("已有相同名称的房型在当前酒店下!");

        CesRoomLayout cesRoomLayout = new CesRoomLayout();
        BeanUtil.copyProperties(cesRoomLayoutDto,cesRoomLayout,CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true));
        cesRoomLayout.setTenantId(TokenUtils.currentTenantId());
        cesRoomLayout.setHotelId(cesRoomLayoutDto.getHotelId());
        cesRoomLayout.setCreateAt(LocalDateTime.now());
        cesRoomLayout.setUpdateAt(LocalDateTime.now());
        cesRoomLayout.setAppState(false);
        cesRoomLayout.setState(true);//默认启用
        cesRoomLayout.setInvalid(false);
        cesRoomLayoutMapper.insert(cesRoomLayout);

        List<CesHousePriceScheme> housePriceSchemeList = housePriceSchemeService.list(Wrappers.<CesHousePriceScheme>lambdaQuery()
                .eq(CesHousePriceScheme::getHotelId, cesRoomLayoutDto.getHotelId()).eq(CesHousePriceScheme::getInvalid, CommonConstant.DEL_FLAG_0));

        List<BusHousePriceSchemeLayout> housePriceSchemeLayouts = new ArrayList<>();
        if (CollUtil.isNotEmpty(housePriceSchemeList)) {
            LoginUser user = TokenUtils.getAuthUser();
            housePriceSchemeList.forEach(item -> {
                BusHousePriceSchemeLayout housePriceSchemeLayout = new BusHousePriceSchemeLayout();
                housePriceSchemeLayout.setTenantId(user.getRelTenantIds());
                housePriceSchemeLayout.setHotelId(cesRoomLayout.getHotelId());
                housePriceSchemeLayout.setSchemeId(item.getId());
                housePriceSchemeLayout.setLayoutId(cesRoomLayout.getId());
                housePriceSchemeLayout.setMoney(cesRoomLayout.getMarketPrice());
                housePriceSchemeLayout.setBreakfastNumber(0);
                housePriceSchemeLayout.setLunchNumber(0);
                housePriceSchemeLayout.setDinnerNumber(0);
                housePriceSchemeLayout.setDelFlag(CommonConstant.DEL_FLAG_0);
                Time time = Time.valueOf("15:00:00");
                housePriceSchemeLayout.setDepartureTime(time);
                housePriceSchemeLayouts.add(housePriceSchemeLayout);
            });
            housePriceSchemeLayoutService.saveBatch(housePriceSchemeLayouts);
        }


        return Result.OK("操作成功!");
    }

    /**
     * 修改房型
     * @param roomLayoutDto
     * @return
     */
    public Result  modifyCesRoomLayout(CesRoomLayoutDto roomLayoutDto){
        //查询是否有相同名称的房型
        QueryWrapper<CesRoomLayout> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(CesRoomLayout.HOTEL_ID, roomLayoutDto.getHotelId());
        queryWrapper.eq(CesRoomLayout.ID,roomLayoutDto.getId());
        queryWrapper.eq(CesRoomLayout.TENANT_ID, TokenUtils.currentTenantId());
        queryWrapper.eq(CesRoomLayout.INVALID, false);
        CesRoomLayout roomLayout = cesRoomLayoutMapper.selectOne(queryWrapper);
        if(ObjectUtils.isEmpty(roomLayout)) return Result.error("房型数据未找到!");

        //忽略空值 不然会覆盖
        BeanUtil.copyProperties(roomLayoutDto,roomLayout, CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true));
        roomLayout.setUpdateAt(LocalDateTime.now());
        cesRoomLayoutMapper.updateById(roomLayout);
        return Result.ok("修改成功!");
    }


    /**
     * @param roomLayoutDto
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public Result removeRoomLayout(CesRoomLayoutRemoveDto roomLayoutDto){
        if (roomLayoutDto.getRoomLayoutIds().isEmpty()){
            throw new JeecgBootException("请选择房型");
        }
        QueryWrapper<CesRoomLayout> queryWrapper = new QueryWrapper<>();
        queryWrapper.in(CesRoomLayout.ID, roomLayoutDto.getRoomLayoutIds());
        queryWrapper.eq(CesRoomLayout.TENANT_ID, TokenUtils.currentTenantId());
        queryWrapper.eq(CesRoomLayout.INVALID, false);
        List<CesRoomLayout> roomLayouts = cesRoomLayoutMapper.selectList(queryWrapper);
        if(CollectionUtil.isEmpty(roomLayouts)) return Result.error("房型数据未找到!");
        roomLayouts.forEach(v -> {
            v.setAppState(false);
            v.setState(false);
            v.setInvalid(true);
            v.setUpdateAt(LocalDateTime.now());
        });
        saveOrUpdateBatch(roomLayouts);
        housePriceSchemeLayoutService.update(Wrappers.<BusHousePriceSchemeLayout>lambdaUpdate()
                .in(BusHousePriceSchemeLayout::getLayoutId, roomLayoutDto.getRoomLayoutIds()).set(BusHousePriceSchemeLayout::getDelFlag, CommonConstant.DEL_FLAG_1));
        return Result.ok("删除成功!");
    }


    /**
     * 修改启用状态
     * @param roomLayoutId
     * @param hotelId
     * @param state
     * @return
     */
    public Result modifyState(String roomLayoutId,String hotelId, Boolean state){
        QueryWrapper<CesRoomLayout> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(CesRoomLayout.HOTEL_ID, hotelId);
        queryWrapper.eq(CesRoomLayout.ID,roomLayoutId);
        queryWrapper.eq(CesRoomLayout.TENANT_ID, TokenUtils.currentTenantId());
        queryWrapper.eq(CesRoomLayout.INVALID, false);
        CesRoomLayout roomLayout = cesRoomLayoutMapper.selectOne(queryWrapper);
        if(ObjectUtils.isEmpty(roomLayout)) return Result.error("房型数据未找到!");
        roomLayout.setState(state);
        roomLayout.setUpdateAt(LocalDateTime.now());
        cesRoomLayoutMapper.updateById(roomLayout);
        return Result.ok("修改成功!");
    }

    /**
     * 修改上架状态
     * @param roomLayoutId
     * @param hotelId
     * @param state
     * @return
     */
    public Result modifyAppState(String roomLayoutId,String hotelId, Boolean state){
        QueryWrapper<CesRoomLayout> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(CesRoomLayout.HOTEL_ID, hotelId);
        queryWrapper.eq(CesRoomLayout.ID,roomLayoutId);
        queryWrapper.eq(CesRoomLayout.TENANT_ID, TokenUtils.currentTenantId());
        queryWrapper.eq(CesRoomLayout.INVALID, false);
        CesRoomLayout roomLayout = cesRoomLayoutMapper.selectOne(queryWrapper);
        if(ObjectUtils.isEmpty(roomLayout)) return Result.error("房型数据未找到!");
        /**
         * @TODO: 验证是否上传大图
         */
        if(StringUtils.isBlank(roomLayout.getCover())) return Result.error("请上传房型大图!");
        roomLayout.setAppState(state);
        roomLayout.setUpdateAt(LocalDateTime.now());
        cesRoomLayoutMapper.updateById(roomLayout);
        return Result.ok("修改成功!");
    }


    /**
     * 根据酒店ID 查询所有房型
     * @param hotelId
     * @return
     */
    public Result getRoomLayoutsByHotelId(String hotelId){

        List<CesRoomLayout> cesRoomLayouts = cesRoomLayoutMapper.selectList(new QueryWrapper<CesRoomLayout>()
                .eq(CesRoomLayout.HOTEL_ID, hotelId)
                .eq(CesRoomLayout.INVALID,false));
        return Result.OK(cesRoomLayouts);

    }







}
